rofiles-fuse: Fix lchown() and hardlink verification for symlinks
authorAlexander Larsson <alexl@redhat.com>
Wed, 6 Sep 2017 07:31:16 +0000 (09:31 +0200)
committerAtomic Bot <atomic-devel@projectatomic.io>
Fri, 8 Sep 2017 20:38:39 +0000 (20:38 +0000)
commit08eaf668275b965d5a692ad48321a14f8c706360
treee0a4d8bfec0b45c0b56cfe4c7fbb135c7dc1b5d7
parent067da211cd63a62cc03dc2745d40b9aa0e64dabc
rofiles-fuse: Fix lchown() and hardlink verification for symlinks

If you lchown("symlink") then we were incorrectly trying to chown the
symlink target, rather than the symlink itself. In particular, this cause
cp -a to fail for a broken symlink. Additionally, it was using the
symlink target when verifying writability, rather than the symlink
itself.

To fix this, we need pass AT_SYMLINK_NOFOLLOW in these cases.

In general, the kernel itself will always resolve any symlinks for us
before calling into the fuse backend, so we should really never do any
symlink following in the fuse fs itself. So, we pro-actively add
NOFOLLOW flags to a few other places:

 truncate:
      In reality this will never be hit, because
      the kernel will resolve symlinks before calling us.
 access:
      It seems the current fuse implementation never calls this
      (faccessat w/AT_SYMLINK_NOFOLLOW never reaches the fuse fs)
      but if this ever is implemented this is the correct behaviour.

We would ideally do `chmod` but this is not implemented on current kernels.
Because we're not multi-threaded, this is OK anyways.

Further, our write verification wasn't correctly handling the case of hardlinked
symlinks, which can occur for `bare` checkouts but *not* `bare-user` which the
tests were using. Change to `bare` mode to verify that.

Closes: #1137
Approved by: alexlarsson
src/rofiles-fuse/main.c
tests/test-rofiles-fuse.sh